package com.osi.mes.qm.services;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import org.dom4j.DocumentException;

import pnuts.lang.Context;

import com.datasweep.compatibility.client.ATColumnDefinition;
import com.datasweep.compatibility.client.ATDefinition;
import com.datasweep.compatibility.client.ATHandler;
import com.datasweep.compatibility.client.ATRow;
import com.datasweep.compatibility.client.ATRowBase;
import com.datasweep.compatibility.client.DependentATRow;
import com.datasweep.compatibility.client.ParentATRow;
import com.datasweep.compatibility.client.Response;
import com.datasweep.plantops.common.constants.IDataTypes;
import com.osi.mes.constants.IModuleConstants;
import com.osi.mes.qm.base.constants.IATComingMat;
import com.osi.mes.qm.base.constants.IBasicConstants;
import com.osi.mes.qm.base.constants.IDonetWebService;
import com.osi.mes.utils.StringUtils;
import com.rockwell.ftpc.framework.common.XMLUtils;
import com.rockwell.ftpc.framework.common.XmlData;
import com.rockwell.ftpc.framework.service.SysBaseService;
import com.rockwell.mes.rtmis.middle.utils.MDUtils;

public class QmWebService extends SysBaseService implements IATComingMat,IDonetWebService,IModuleConstants{

	private static QmWebService instatnce = null;
	private QmWebService(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}
	
	public static QmWebService getInstance(Context context)
	{
		if (instatnce == null)
		{
			synchronized(QmWebService.class)
			{
				if (instatnce == null)
				{
					instatnce = new QmWebService(context);
				}
			}
		}
		return instatnce;
	}
	
	//接收原辅料检验的目检信息
	public String[] receiverRawMatRecChkData(String strXml)
	{
		return createATRows(AT_RAW_ACC_MAT_REC_CHK,RAW_ACC_REC_PROD_INFO,strXml,"recRawMaterialInfo");
	}
	
	//接收内外包材目检信息
	public String[] receiveInnerPackageRecChkData(String strXml)
	{
		return createATRows(IN_OUT_SOURCE_REC_CHK,IN_OUT_SOURCE_PROD_INFO,strXml,"recInOutSourceInfo");
	}
	
	//接收化学品目检信息
	public String[] receiveChemicalProdChkData(String strXml)
	{
		return createATRows(CHEMICAL_PROD_CHK,CHEMICAL_PROD_INFO,strXml,"reccCheProdInfo");
	}
	
	private String[] createATRows(String parentATDef,String dependentATDef,String xmlStr,String prodInfo)
	{
		String errorMsg = "";
		String result = "";
		String[] results = new String[1];
		try
		{
			System.out.println(xmlStr);
			XmlData xmlData = XMLUtils.strToXMLData(xmlStr);
//			XmlData xmlData = XMLUtils.fileToXMLData(xmlStr);
			ATHandler atHandler = getFunctions().createATHandler(parentATDef);
			ATDefinition atDef = getFunctions().getATDefinition(parentATDef);
			ParentATRow parentATRow = (ParentATRow)atHandler.createATRow();
			
			setData(atDef,parentATRow,xmlData);
			Response res = parentATRow.save(getFunctions().getDBTime(), null, null);
			if(res.isOk())
			{
				ArrayList<?> rawMatInfos =  xmlData.get(prodInfo);
				if(rawMatInfos == null || rawMatInfos.size() == 0)
					 throw new Exception("Error: 目检单中不存在物料，批次信息");
				
				ATDefinition depdentATDef = getFunctions().getATDefinition(dependentATDef);
				for(int j=0;j<rawMatInfos.size();j++)
				{
					Object prodInfoObj = rawMatInfos.get(j);
					String xml = XMLUtils.toXMLStr((Hashtable)prodInfoObj);
					prodInfoObj = XMLUtils.strToXMLData(xml);
					if(prodInfoObj instanceof XmlData)
					{
						XmlData prodInfoData = (XmlData)prodInfoObj;
						res = parentATRow.createDependentATRow(depdentATDef, null);
						DependentATRow deptATRow = (DependentATRow)res.getResult();
						setData(depdentATDef,deptATRow,prodInfoData);
					}
				}
				
				res = parentATRow.save(getFunctions().getDBTime(), null, null);
				if(res.isError())
				{
					throw new Exception("Error: "+res.getFirstErrorMessage());
				}
			}
		}
		catch (Exception e)
		{
			logError(e,MODULE_QM,"接收WMS目检单失败.");
			errorMsg = e.getLocalizedMessage();
		}
	
		
		if(StringUtils.isNotNull(errorMsg))
			result = "1";
		else
			result = "0";
		results[0] = "<MessageResult><Status>"+result+"</Status><LastErrMsg>"+errorMsg+"</LastErrMsg></MessageResult>";
		return results;
	}
	
	private ATRowBase setData(ATDefinition atDef,ATRowBase atRow,XmlData xmlData) throws ParseException
	{
		List<ATColumnDefinition> columnAtDefs = atDef.getATColumnDefinitions();
		for(int i=0;i<columnAtDefs.size();i++)
		{
			ATColumnDefinition atColumnDef = columnAtDefs.get(i);
			Object val = xmlData.getValue(atColumnDef.getName());
			
			if(val == null || val == "")
				continue;
			
			short dataType = atColumnDef.getDataType();
			if(dataType == IDataTypes.TYPE_DATETIME)
			{
				val = StringUtils.getTimeFromStr(val.toString(), "yyyy-MM-dd");
			}
			else if(dataType == IDataTypes.TYPE_BOOLEAN)
			{
				val = "true".equals(val);
			}
			else
			{
				val = val.toString();
			}
			
			if(val!=null)
				atRow.setValue(atColumnDef.getName(), val);
		}
		
		return atRow;
	}
	
	/**
	 * 通知WMS检验结果
	 * @param chkResult
	 * @return
	 * @throws Exception
	 */
	public boolean informComingMatChkResult(ATRow chkResult)throws Exception
	{
		try
		{
			ATDefinition atDef = chkResult.getATDefinition();
			if(atDef == null)
				return false;
			
			String atDefName = atDef.getName();
			if(atDef.getName().equals(IATComingMat.AT_RAW_ACC_MAT_CHK))
			{
				return informRawAccMatChkResult(chkResult);
			}
			else if(atDefName.equals(IATComingMat.AT_IN_OUT_SOURCE_CHK))
				return informInOutSourceChkResult(chkResult);
			else if(atDefName.equals(IATComingMat.AT_CHEMICAL_PROD_CHK))
				return informChemicalProdChkResult(chkResult);
			else if(atDefName.equals("QMProdShipOutReport"))
				return informShipReportChkResToWMS(chkResult);
			
		}
		catch(Exception exp)
		{
			logError(exp,"通知WMS物料检验信息失败了.","物料检验");
			throw exp;
		}
		return false;
		
	}
	
	//原，辅料检验结果
	public boolean informRawAccMatChkResult(ATRow matChkResult)throws Exception
	{
		return informComingMatChkResult(matChkResult,IATComingMat.DEPT_AT_RAW_ACC_LOT_MAT_REL);
	}
	
	//内外包材
	public boolean informInOutSourceChkResult(ATRow matChkResult)throws Exception
	{
		return informComingMatChkResult(matChkResult,IATComingMat.DEPT_SOURCE_LOT_MAT_REL);
	}
	
	//化学品检验结果
	public boolean informChemicalProdChkResult(ATRow matChkResult)throws Exception
	{
		return informComingMatChkResult(matChkResult,IATComingMat.DEPT_AT_CHE_PROD_LOT_MAT_REL);
	}
	
	//发送成品批次审核信息
	public boolean informShipReportChkResToWMS(ATRow shipReport) throws Exception
	{
		if(!(shipReport instanceof ParentATRow))
		{
			return false;
		}
		
		ParentATRow pATRow = (ParentATRow)shipReport;
		Vector<DependentATRow> deptATRows = pATRow.getDependentATRows();
		
		String auditUser = (String)shipReport.getValue("audit_user");
		String operate = "QualityInspectionResult";
		String orderNum = (String)shipReport.getValue("order_num");
		String partNumber = (String)shipReport.getValue("prod_name");
		List<Object[]> chkItems = new ArrayList<Object[]>();
		for(int i=0;i<deptATRows.size();i++)
		{
			int handMh = getHandCode((String)deptATRows.get(i).getValue("lot_handle"));
			String lot = deptATRows.get(i).getValue("lot_num").toString();
			String maId =  partNumber;
			Object[] strs = new Object[4];
			strs[0] = lot;
			strs[1] = maId;
			strs[2] = handMh;
			strs[3] = "";
			chkItems.add(strs);
		}
		
		return makeCommonXmlData(operate,auditUser,orderNum,chkItems);
	}
	
	private boolean makeCommonXmlData(String operate,String auditUser,String orderNum,List<?> chkItems) throws Exception
	{
		Hashtable<String, ArrayList<Object>> data = new Hashtable<String, ArrayList<Object>>();
		data.put(OPERATE, toTransferValue(operate));
		data.put(OPERATOR, toTransferValue(auditUser));
		
		Hashtable<String, ArrayList<Object>> wbsBillHeadData = new Hashtable<String, ArrayList<Object>>();
		Hashtable<String, ArrayList<Object>> allData = new Hashtable<String, ArrayList<Object>>();
		Hashtable<String, ArrayList<Object>> requestBillData = new Hashtable<String, ArrayList<Object>>();
		Hashtable<String, ArrayList<Object>> itemsData = new Hashtable<String, ArrayList<Object>>();
		
		wbsBillHeadData.put(BILLNO, toTransferValue(orderNum));
		wbsBillHeadData.put(BILLTYPE, toTransferValue(""));
		wbsBillHeadData.put(BILLDATE, toTransferValue(""));
		wbsBillHeadData.put(REF1, toTransferValue(""));
		wbsBillHeadData.put(REF2, toTransferValue(""));
		wbsBillHeadData.put(REF3, toTransferValue(""));
		wbsBillHeadData.put(REF4, toTransferValue(""));
		wbsBillHeadData.put(REF5, toTransferValue(""));
		wbsBillHeadData.put(WHSCD, toTransferValue(""));
		wbsBillHeadData.put(TYPE, toTransferValue(""));
		
		ArrayList<Object> itemsList = new ArrayList<Object>();
		for(int i=0;i<chkItems.size();i++)
		{
				Object[] valus = (Object[])chkItems.get(i);
			 	Hashtable<String, ArrayList<Object>> wbsBillItemData = new Hashtable<String, ArrayList<Object>>();
				wbsBillItemData.put(BILLNO, toTransferValue(orderNum));
				wbsBillItemData.put(SUPPLIERID, toTransferValue(valus[3]));
				wbsBillItemData.put(SUPPLIERNAME, toTransferValue(""));
				wbsBillItemData.put(ITEM_ID, toTransferValue(valus[1]));
				wbsBillItemData.put(ITEM_NAME, toTransferValue(""));
				wbsBillItemData.put(BILLTYPE, toTransferValue(""));
				wbsBillItemData.put(BILLDATE, toTransferValue(""));
				wbsBillItemData.put(IN_DATE, toTransferValue(""));
				wbsBillItemData.put(OUT_DATE, toTransferValue(""));
				wbsBillItemData.put(MAT_LAB, toTransferValue(""));
				wbsBillItemData.put(BATCH_NO, toTransferValue(valus[0]));
				wbsBillItemData.put(QTY, toTransferValue(0));
				wbsBillItemData.put(REF1,toTransferValue(valus[2]));
				XmlData xmlData = new XmlData(WBSBILLITEM,wbsBillItemData);
				if(!itemsList.contains(xmlData))
					itemsList.add(xmlData);
		}
		
		itemsData.put(WBSBILLITEM, itemsList);
		
		XmlData itemXmlData = new XmlData(ITEMS,itemsData);
		wbsBillHeadData.put(ITEMS, toTransferValue(itemXmlData));
		wbsBillHeadData.put(RESULT, toTransferValue("false"));
		XmlData headData = new XmlData(WBSBILLHEAD,wbsBillHeadData);
		requestBillData.put(WBSBILLHEAD, toTransferValue(headData));
		
		XmlData requestBillXmlData = new XmlData(REQUESTBILL,requestBillData);
		data.put(REQUESTBILL, toTransferValue(requestBillXmlData));
		
		XmlData rootData = new XmlData(XML_ROOT_NAME,data);
		allData.put(XML_ROOT_NAME, toTransferValue(rootData));
		String xmlStr =XMLUtils.toXMLStr(allData);
		
		xmlStr = xmlStr.replaceAll("<xml>", "");
		xmlStr = xmlStr.replaceAll("</xml>", "");
		System.out.println(xmlStr);
		String result = MDUtils.invokeDNetWebService(
				END_POINT, NAME_SPACE, METHOD_NAME, SOAP_ACTION, PARAMETER_NAME, xmlStr);
		
		XmlData xmlData = XMLUtils.strToXMLData(result);
		List<Object> resultList = (List<Object>)xmlData.get(RESULT);
		List<Object> messageList = (List<Object>)xmlData.get(MESSAGE);
		if(resultList == null || resultList.size()==0)
			return false;
		
		String res = (String)resultList.get(0);
		if(!"true".equals(res))
		{
			throw new Exception("通知WMS批次检验信息失败了,原因为"+messageList.get(0));
		}
			
		return true;
	}
	
	private int getHandCode(String handMh)
	{
		int handCode = 0;
		if("返工".equals(handMh))
			handCode = IBasicConstants.REWORK;
		else if("销毁".equals(handMh))
			handCode =  IBasicConstants.DESTORY;
		else if("改为其他用途".equals(handMh) || "转为他用".equals(handMh))
			handCode =  IBasicConstants.CHANGE;
		else if("放行".equals(handMh))
			handCode =  IBasicConstants.NORMAL;
		else if("退货".equals(handMh))
			handCode =  IBasicConstants.RETURN;
		else if("让步接收".equals(handMh))
			handCode =  IBasicConstants.RECEIPT;
		
		return handCode;
	}
	
	//发送来料检验结果到WMS
	public boolean informComingMatChkResult(ATRow matChkResult,String deptName)throws Exception
	{
		if(!(matChkResult instanceof ParentATRow))
		{
			return false;
		}
		
		ParentATRow pATRow = (ParentATRow)matChkResult;
		Vector<DependentATRow> deptATRows = pATRow.getDependentATRows(getFunctions().getATDefinition(deptName));
		
		String auditUser = (String)matChkResult.getValue("audit_user");
		String vendorID = (String)matChkResult.getValue("vendorID");
		String operate = "QualityInspectionResult";
		String orderNum = "";
		int handMh = getHandCode((String)matChkResult.getValue("handle_mh"));
		List<Object[]> chkItems = new ArrayList<Object[]>();
		for(int i=0;i<deptATRows.size();i++)
		{
			String lot = deptATRows.get(i).getValue("lot_no").toString();
			String maId = deptATRows.get(i).getValue("mat_id").toString();
			boolean chkState = (Boolean) deptATRows.get(i).getValue("chk_state");
			Object[] strs = new Object[4];
			strs[0] = lot;
			strs[1] = maId;
			if(handMh == IBasicConstants.RECEIPT)
			{
				if(chkState == true)
					strs[2] =  handMh;
				else
					strs[2] =  IBasicConstants.RETURN;
			}
			else
			{
				strs[2] = handMh;
			}
			strs[3] = vendorID;
			chkItems.add(strs);
		}
		
		return makeCommonXmlData(operate,auditUser,orderNum,chkItems);
	}
	
	protected static ArrayList<Object> toTransferValue(Object obj) {
		ArrayList<Object> data = new ArrayList<Object>();
		if(obj == null)
			obj = "";
		data.add(obj);
		return data;
	}
	
	public static void main(String[] args) throws DocumentException
	{
		String filePath = "d:\\test.xml";

//		String strXml = "";
//		XmlData xmlData = XMLUtils.fileToXMLData(filePath);
//		Hashtable<String, ArrayList<Object>> data = xmlData.getData();
//		Iterator<Entry<String, ArrayList<Object>>> iter = data.entrySet().iterator();
//		while(iter.hasNext())
//		{
//			Entry<String, ArrayList<Object>> enterySet = iter.next();
//			String key = enterySet.getKey();
//			ArrayList<Object> val = enterySet.getValue();
//			
//			System.out.println("key: "+key);
//			if(val!=null && val.size()>0)
//			{
//				for(int i=0;i<val.size();i++)
//				{
//					System.out.print("val: "+val.get(i));
//				}
//				
//				System.out.println("-------------");
//			}
//			
//		}
	}
}
